home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / mawk.zip / ZMALLOC.C < prev    next >
C/C++ Source or Header  |  1991-04-09  |  3KB  |  130 lines

  1.  
  2. /********************************************
  3. zmalloc.c
  4. copyright 1991, Michael D. Brennan
  5.  
  6. This is a source file for mawk, an implementation of
  7. the Awk programming language as defined in
  8. Aho, Kernighan and Weinberger, The AWK Programming Language,
  9. Addison-Wesley, 1988.
  10.  
  11. See the accompaning file, LIMITATIONS, for restrictions
  12. regarding modification and redistribution of this
  13. program in source or binary form.
  14. ********************************************/
  15.  
  16. /*$Log:    zmalloc.c,v $
  17.  * Revision 2.2  91/04/09  12:39:45  brennan
  18.  * added static to funct decls to satisfy STARDENT compiler
  19.  * 
  20.  * Revision 2.1  91/04/08  08:24:17  brennan
  21.  * VERSION 0.97
  22.  * 
  23. */
  24.  
  25. /*  zmalloc.c  */
  26. #include  "mawk.h"
  27. #include  "zmalloc.h"
  28.  
  29. void PROTO( mawk_exit, (int) ) ;
  30.  
  31. /*
  32.   zmalloc() gets mem from malloc() in CHUNKS of 2048 bytes
  33.   and cuts these blocks into smaller pieces that are multiples
  34.   of eight bytes.  When a piece is returned via zfree(), it goes
  35.   on a linked linear list indexed by its size.  The lists are
  36.   an array, pool[].
  37.  
  38.   E.g., if you ask for 22 bytes with p = zmalloc(22), you actually get
  39.   a piece of size 24.  When you free it with zfree(p,22) , it is added
  40.   to the list at pool[2].
  41. */
  42.  
  43. #define ZBLOCKSZ    8    
  44. #define ZSHIFT      3
  45. #define POOLSZ      16
  46.  
  47. #define  CHUNK          256    
  48.         /* number of blocks to get from malloc */
  49.  
  50. static PTR  PROTO( emalloc, (unsigned) ) ;
  51. void PROTO( errmsg, (int , char *, ...) ) ;
  52.  
  53. static PTR emalloc(size)
  54.   unsigned size ;
  55. { PTR p ;
  56.  
  57.   if( !(p = malloc(size)) )
  58.   { errmsg(0, "out of memory") ; mawk_exit(1) ; }
  59.   return p ;
  60. }
  61.  
  62.  
  63. typedef  union  zblock {
  64. char dummy[ZBLOCKSZ] ;
  65. union zblock *link ;
  66. }  ZBLOCK  ;
  67.  
  68. /* ZBLOCKS of sizes 1, 2, ... 16
  69.    which is bytes of sizes 8, 16, ... , 128
  70.    are stored on the linked linear lists in
  71.    pool[0], pool[1], ... , pool[15]
  72. */
  73.  
  74. static  ZBLOCK  *pool[POOLSZ] ;
  75.  
  76. PTR   zmalloc( size )
  77.   unsigned size ;
  78. { register unsigned blocks ;
  79.   register ZBLOCK *p ;
  80.   static  unsigned amt_avail ;
  81.   static  ZBLOCK  *avail ;
  82.  
  83.   if ( size > POOLSZ * ZBLOCKSZ )  return emalloc(size) ;
  84.  
  85.   blocks = (size >> ZSHIFT) + ((size & (ZBLOCKSZ-1)) != 0) ;
  86.  
  87.   if ( p = pool[blocks-1] )
  88.   { pool[blocks-1] = p->link ; return (PTR) p ; }
  89.  
  90.   if ( blocks > amt_avail )
  91.   { if ( amt_avail ) /* free avail */
  92.     { avail->link = pool[--amt_avail] ; pool[amt_avail] = avail ; }
  93.     if ( !(avail = (ZBLOCK *) malloc(CHUNK*ZBLOCKSZ)) )
  94.     { /* if we get here, almost out of memory */
  95.         amt_avail = 0 ;   return  emalloc(size) ; }
  96.     amt_avail = CHUNK ;
  97.   }
  98.   
  99.   /* get p from the avail pile */
  100.   p = avail ; avail += blocks ; amt_avail -= blocks ; 
  101.   return (PTR) p ;
  102. }
  103.  
  104. void  zfree( p, size)
  105.   register PTR p ;  unsigned size ;
  106. { register int index ; ;
  107.  
  108.   if ( size > POOLSZ * ZBLOCKSZ )  free(p) ;
  109.   else
  110.   {
  111.     index  = (size >> ZSHIFT) + ((size & (ZBLOCKSZ-1)) != 0) - 1;
  112.     ((ZBLOCK *) p)->link = pool[index] ;
  113.     pool[index] = (ZBLOCK *) p ;
  114.   }
  115. }
  116.  
  117. PTR  zrealloc( p, old_size, new_size )
  118.   register PTR  p ;
  119.   unsigned old_size, new_size ;
  120. { register PTR q ;
  121.  
  122.   (void) memcpy(q = zmalloc(new_size), p, 
  123.                 old_size < new_size ? old_size : new_size) ;
  124.  
  125.   zfree(p, old_size) ;
  126.   return q ;
  127. }
  128.  
  129.  
  130.